package org.chen.service.impl;

import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.chen.exception.NewsException;
import org.chen.model.dto.ArticleTagDTO;
import org.chen.model.mongodb.ArticleDocument;
import org.chen.model.mongodb.ArticleTag;
import org.chen.model.quey.TagQueryParam;
import org.chen.response.Page;
import org.chen.utils.PageHelper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;

// 3. 标签管理服务
@Service
@Slf4j
public class TagManagementService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private StringRedisTemplate redisTemplate;

    private static final String TAG_CACHE_KEY = "article:tags:";
    private static final long CACHE_DURATION = 1; // 小时


    /**
     * 刷新缓存
     */
    private void refreshCache(ArticleTag tag) {
        String cacheKey = TAG_CACHE_KEY + tag.getId();
        redisTemplate.opsForValue().set(cacheKey, JSON.toJSONString(tag), CACHE_DURATION, TimeUnit.HOURS);
        // 更新标签列表缓存
        redisTemplate.delete(TAG_CACHE_KEY + "list");
    }

    /**
     * 删除缓存
     */
    private void removeCache(String tagId) {
        redisTemplate.delete(TAG_CACHE_KEY + tagId);
        redisTemplate.delete(TAG_CACHE_KEY + "list");
    }

    /**
     /**
     * 保存标签到标签库
     */
    private void saveTags(Set<String> tags) {
        tags.forEach(tag -> {
            Query query = new Query(Criteria.where("name").is(tag));
            if (!mongoTemplate.exists(query, ArticleTag.class)) {
                ArticleTag articleTag = new ArticleTag();
                articleTag.setName(tag);
                articleTag.setIsSystem(false);
                articleTag.setWeight(0);
                articleTag.setCategory(tag);
                articleTag.setDescription(tag);
                articleTag.setCreateTime(new Date());
                articleTag.setUpdateTime(new Date());
                ArticleTag saved = mongoTemplate.save(articleTag);
                refreshCache(saved);
            }
        });
    }

    /**
     * 管理员手动添加标签
     */
    public ArticleTag addTag(ArticleTagDTO tagDTO) {
        // 检查标签名是否已存在
        Query query = new Query(Criteria.where("name").is(tagDTO.getName()));
        if (mongoTemplate.exists(query, ArticleTag.class)) {
            throw new NewsException("标签名已存在");
        }

        ArticleTag tag = new ArticleTag();
        BeanUtils.copyProperties(tagDTO, tag);
        tag.setIsSystem(false);
        tag.setCreateTime(new Date());
        tag.setUpdateTime(new Date());
        ArticleTag saved = mongoTemplate.save(tag);
        refreshCache(saved);
        return saved;
    }

    /**
     * 更新标签
     */
    public ArticleTag updateTag(String tagId, ArticleTagDTO tagDTO) {
        ArticleTag tag = mongoTemplate.findById(tagId, ArticleTag.class);
        if (tag != null) {
            // 检查新名称是否与其他标签重复
            if (!tag.getName().equals(tagDTO.getName())) {
                Query query = new Query(Criteria.where("name").is(tagDTO.getName()));
                if (mongoTemplate.exists(query, ArticleTag.class)) {
                    throw new NewsException("标签名已存在");
                }
            }

            BeanUtils.copyProperties(tagDTO, tag);
            tag.setUpdateTime(new Date());
            ArticleTag updated = mongoTemplate.save(tag);
            refreshCache(updated);
            return updated;
        }
        return null;
    }

    /**
     * 删除标签
     */
    public void deleteTag(String tagId) {
        ArticleTag tag = mongoTemplate.findById(tagId, ArticleTag.class);
        if (tag != null) {
            if (tag.getIsSystem()) {
                throw new NewsException("系统标签不能删除");
            }
            mongoTemplate.remove(tag);
            removeCache(tagId);
        }
    }

    /**
     * 查询标签列表
     */
    public Page<ArticleTag> getTags(TagQueryParam queryParam) {
        // 如果没有查询条件，尝试从缓存获取
        if (StringUtils.isEmpty(queryParam.getKeyword())
                && StringUtils.isEmpty(queryParam.getCategory())
                && queryParam.getIsSystem() == null) {
            String cacheKey = TAG_CACHE_KEY + "list";
            String cacheValue = redisTemplate.opsForValue().get(cacheKey);
            if (cacheValue != null) {
                List<ArticleTag> tagList = JSON.parseArray(cacheValue, ArticleTag.class);
                return PageHelper.getPage(tagList, queryParam.getPage(), queryParam.getSize());
            }
        }

        Query query = new Query();

        if (StringUtils.hasText(queryParam.getKeyword())) {
            query.addCriteria(Criteria.where("name").regex(queryParam.getKeyword()));
        }
        if (StringUtils.hasText(queryParam.getCategory())) {
            query.addCriteria(Criteria.where("category").is(queryParam.getCategory()));
        }
        if (queryParam.getIsSystem() != null) {
            query.addCriteria(Criteria.where("isSystem").is(queryParam.getIsSystem()));
        }

        Page<ArticleTag> page = PageHelper.getPage(query, ArticleTag.class,
                queryParam.getPage(), queryParam.getSize(), mongoTemplate);

        // 缓存查询结果
        if (page != null && page.getRecords() != null) {
            String cacheKey = TAG_CACHE_KEY + "list";
            redisTemplate.opsForValue().set(cacheKey,
                    JSON.toJSONString(page.getRecords()),
                    CACHE_DURATION,
                    TimeUnit.HOURS);
        }

        return page;
    }

    /**
     * 处理文章标签
     */
    public List<String> processArticleTags(ArticleDocument article, List<String> manualTags) {
        // 1. 合并手动标签和提取的关键词
        Set<String> allTags = new HashSet<>();
        if (manualTags != null) {
            allTags.addAll(manualTags);
        }

        // 2. 保存新的标签到标签库
        saveTags(allTags);

        return new ArrayList<>(allTags);
    }

    /**
     * 刷新标签缓存,从数据库重新加载
     */
    public Page<ArticleTag> refresh() {
        // 1. 清除所有标签相关的缓存
        Set<String> keys = redisTemplate.keys(TAG_CACHE_KEY + "*");
        if (keys != null && !keys.isEmpty()) {
            redisTemplate.delete(keys);
        }

        // 2. 从数据库重新查询所有标签
        Query query = new Query();
        Page<ArticleTag> page = PageHelper.getPage(query, ArticleTag.class, 1, Integer.MAX_VALUE, mongoTemplate);

        // 3. 重建缓存
        if (page != null && page.getRecords() != null) {
            // 缓存标签列表
            String listCacheKey = TAG_CACHE_KEY + "list";
            redisTemplate.opsForValue().set(listCacheKey,
                    JSON.toJSONString(page.getRecords()),
                    CACHE_DURATION,
                    TimeUnit.HOURS);

            // 缓存每个标签的详细信息
            page.getRecords().forEach(tag -> {
                String cacheKey = TAG_CACHE_KEY + tag.getId();
                redisTemplate.opsForValue().set(cacheKey,
                        JSON.toJSONString(tag),
                        CACHE_DURATION,
                        TimeUnit.HOURS);
            });
        }

        return page;
    }
}
